﻿#include "FITKAbaConnectorSection.h"
#include "FITKAbaConnectorBehaviorDamping.h"
#include "FITKAbaConnectorBehaviorElasticity.h"
#include "FITKAbaConnectorBehaviorPlasticity.h"
#include "FITKAbaConnectorBehaviorLock.h"
#include "FITKAbaConnectorBehaviorStop.h"
#include <QMetaEnum>

Interface::FITKAbaConnectorSection::~FITKAbaConnectorSection()
{
    this->clearAllBehaviors();
}

bool Interface::FITKAbaConnectorSection::copy(FITKAbstractDataObject *obj)
{
    bool ok = Core::FITKAbstractNDataObject::copy(obj);
    if (!ok)
        return false;
    FITKAbaConnectorSection* cs = dynamic_cast<FITKAbaConnectorSection*>(obj);
    if (cs == nullptr)
        return false;
    this->clearAllBehaviors();
    for (FITKAbaConnectorBehavior* bh : cs->m_behaviorOptions)
    {
        auto type = bh->getBehaviorType();
        FITKAbaConnectorBehavior* newBh = this->addBehavior(type);
        switch (type) {
        case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Elasticity:
        {
            FITKAbaConnectorBehaviorElasticity* old = dynamic_cast<FITKAbaConnectorBehaviorElasticity*>(bh);
            FITKAbaConnectorBehaviorElasticity* newb = dynamic_cast<FITKAbaConnectorBehaviorElasticity*>(newBh);
            if ((old != nullptr) && (newb != nullptr))
                *newb = *old;
        }
            break;
        case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Plasticity:
        {
            FITKAbaConnectorBehaviorPlasticity* old = dynamic_cast<FITKAbaConnectorBehaviorPlasticity*>(bh);
            FITKAbaConnectorBehaviorPlasticity* newb = dynamic_cast<FITKAbaConnectorBehaviorPlasticity*>(newBh);
            if ((old != nullptr) && (newb != nullptr))
                *newb = *old;
        }
            break;
        case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Damping:
        {
            FITKAbaConnectorBehaviorDamping* old = dynamic_cast<FITKAbaConnectorBehaviorDamping*>(bh);
            FITKAbaConnectorBehaviorDamping* newb = dynamic_cast<FITKAbaConnectorBehaviorDamping*>(newBh);
            if ((old != nullptr) && (newb != nullptr))
                *newb = *old;
        }
            break;
        case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Stop:
        {
            FITKAbaConnectorBehaviorStop* old = dynamic_cast<FITKAbaConnectorBehaviorStop*>(bh);
            FITKAbaConnectorBehaviorStop* newb = dynamic_cast<FITKAbaConnectorBehaviorStop*>(newBh);
            if ((old != nullptr) && (newb != nullptr))
                *newb = *old;
        }
            break;
        case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Lock:
        {
            FITKAbaConnectorBehaviorLock* old = dynamic_cast<FITKAbaConnectorBehaviorLock*>(bh);
            FITKAbaConnectorBehaviorLock* newb = dynamic_cast<FITKAbaConnectorBehaviorLock*>(newBh);
            if ((old != nullptr) && (newb != nullptr))
                *newb = *old;
        }
            break;
        default:
            break;
        }
    }
    m_category = cs->m_category;
    m_assebledComplexType = cs->m_assebledComplexType;
    m_translationalType = cs->m_translationalType;
    m_rotationalType = cs->m_rotationalType;
    return true;
}

Interface::FITKAbaConnectorSection::Category Interface::FITKAbaConnectorSection::getCategory() const
{
    return m_category;
}

void Interface::FITKAbaConnectorSection::setCategory(Category type)
{
    m_category = type;
}

const QList<Interface::FITKAbaConnectorBehavior *> Interface::FITKAbaConnectorSection::getAllBehaviors() const
{
    return m_behaviorOptions;
}

Interface::FITKAbaConnectorBehavior *Interface::FITKAbaConnectorSection::addBehavior(FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType type)
{
    FITKAbaConnectorBehavior* newBh{nullptr};
    switch (type) {
    case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Elasticity:
        newBh = new FITKAbaConnectorBehaviorElasticity();
        break;
    case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Plasticity:
        newBh = new FITKAbaConnectorBehaviorPlasticity();
        break;
    case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Damping:
        newBh = new FITKAbaConnectorBehaviorDamping();
        break;
    case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Stop:
        newBh = new FITKAbaConnectorBehaviorStop();
        break;
    case FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Lock:
        newBh = new FITKAbaConnectorBehaviorLock();
        break;
    default:
        break;
    }
    if (newBh != nullptr)
        m_behaviorOptions.append(newBh);
    return newBh;
}

void Interface::FITKAbaConnectorSection::addBehavior(FITKAbaConnectorBehavior* bh)
{
    if (!m_behaviorOptions.contains(bh))
        m_behaviorOptions.append(bh);
}

void Interface::FITKAbaConnectorSection::removeBehavior(FITKAbaConnectorBehavior *bh)
{
    m_behaviorOptions.removeAll(bh);
    delete bh;
}

void Interface::FITKAbaConnectorSection::clearAllBehaviors()
{
    for (auto b: m_behaviorOptions)
        delete b;
    m_behaviorOptions.clear();
}


namespace Interface {
FITKAbaConnectorSection::AssembledComplexType FITKAbaConnectorSection::getAssembledComplexType() const
{
    return m_assebledComplexType;
}

void FITKAbaConnectorSection::setAssebledComplexType(AssembledComplexType newAssebledComplexType)
{
    m_assebledComplexType = newAssebledComplexType;
}

FITKAbaConnectorSection::TranslationalType FITKAbaConnectorSection::getTranslationalType() const
{
    return m_translationalType;
}

void FITKAbaConnectorSection::setTranslationalType(TranslationalType newTranslationalType)
{
    m_translationalType = newTranslationalType;
}

FITKAbaConnectorSection::RotationalType FITKAbaConnectorSection::getRotationalType() const
{
    return m_rotationalType;
}

void FITKAbaConnectorSection::setRotationalType(RotationalType newRotationalType)
{
    m_rotationalType = newRotationalType;
}

QString FITKAbaConnectorSection::getTypeString()
{
    //根据当前类型，返回类型字符串
    QString name{};
    FITKAbaConnectorSection::Category type = this->getCategory();
    switch (type) {
    case FITKAbaConnectorSection::Category::AssembledComplex:
    {
        QMetaEnum m = QMetaEnum::fromType<FITKAbaConnectorSection::AssembledComplexType>();
        name = m.valueToKey(this->getAssembledComplexType());
    }
        break;
    case FITKAbaConnectorSection::Category::Basic:
    {
        TranslationalType tt = this->getTranslationalType();
        RotationalType rt = this->getRotationalType();
        QMetaEnum tm = QMetaEnum::fromType<TranslationalType>();
        QMetaEnum rm = QMetaEnum::fromType<RotationalType>();
        if (tt == TranslationalType::NoneTranslational)
            name = rm.valueToKey((int)rt);
        else if (rt == RotationalType::NoneRotational)
            name = tm.valueToKey((int)tt);
        else
            name = QString("%1 + %2").arg(tm.valueToKey((int)tt)).arg(rm.valueToKey((int)rt));
    }
        break;
    default:
        break;
    }
    return name;
}

}
